package com.gyh.system.sys.utils;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import com.google.common.collect.Sets;
import com.gyh.system.common.tools.StringUtils;
import com.gyh.system.common.utils.CacheUtils;
import com.gyh.system.common.utils.SpringContextHolder;
import com.gyh.system.sys.dao.MenuDao;
import com.gyh.system.sys.dao.RoleDao;
import com.gyh.system.sys.dao.UserDao;
import com.gyh.system.sys.entity.Menu;
import com.gyh.system.sys.entity.Role;
import com.gyh.system.sys.entity.User;
import com.gyh.system.sys.oauth.MyRealm.Principal;

/**
 * 
 * @author 作者 gyh
 * @version 创建时间：2018年7月10日 下午11:35:26
 */
public class UserUtils {

	private static final Logger logger = LoggerFactory.getLogger(UserUtils.class);

	private static UserDao userDao = SpringContextHolder.getBean(UserDao.class);
	private static RoleDao roleDao = SpringContextHolder.getBean(RoleDao.class);
	private static MenuDao menuDao = SpringContextHolder.getBean(MenuDao.class);
	
	public static final String USER_CACHE = "userCache";
	public static final String USER_CACHE_ID_ = "id_";
	public static final String USER_CACHE_LOGIN_NAME_ = "loginName_";
	public static final String CACHE_AREA_MAP_LIST = "areaMapList";
	public static final String CACHE_PERMISSION_LIST = "permissionList";
	
	
	/**
	 * 根据用户的ID获取用户信息
	 */
	public static User get(Long id) {
		User user = (User) CacheUtils.get(USER_CACHE,USER_CACHE_ID_+id);
		if (user == null) {
			user = userDao.get(id);
			if (user == null){
				return null;
			}
			user.setRoleList(roleDao.findList(new Role(user)));
			CacheUtils.put(USER_CACHE,USER_CACHE_ID_+user.getId(), user);
			CacheUtils.put(USER_CACHE,USER_CACHE_LOGIN_NAME_+user.getLoginName(), user);
		}
		return user;
	}
	
	
	
	/**
	 * 获取当前用户
	 * @return 取不到user返回 new User()
	 */
	public static User getUser() {
		Principal principal = getPrincipal();
		if (principal != null) {
			User user = get(principal.getId());
			if (user != null) {
				return user;
			}
			return new User();
		}
		return new User();
	}

	/**
	 * 获取当前登录者对象
	 */
	public static Principal getPrincipal() {
		try {
			Subject subject = SecurityUtils.getSubject();
			if (subject == null) {
				logger.debug("getPrincipal error,please check");
			}
			Principal principal = (Principal) subject.getPrincipal();
			if (principal != null) {
				return principal;
			}
		} catch (UnavailableSecurityManagerException e) {
			logger.error("UnavailableSecurityManagerException,please check");
		} catch (InvalidSessionException e) {
			logger.error("InvalidSessionException,please check");
		}
		return null;
	}

	/**
	 * 获取授权主要对象
	 */
	public static Subject getSubject() {
		return SecurityUtils.getSubject();
	}

	/**
	 * 获取当前用户的所有权限列表
	 */
	public static Set<String> getUserPermissionList() {
		User user = getUser();
		
		@SuppressWarnings("unchecked")
		Set<String> permsSet = (Set<String>)CacheUtils.get(CACHE_PERMISSION_LIST, CACHE_PERMISSION_LIST+"_"+user.getId());;
		
		if (CollectionUtils.isEmpty(permsSet)) {
			List<String> permsList = null;
			//判断用户是否是管理员
			if (user.isAdmin()) {
				List<Menu> menuList = menuDao.findAllList();
				permsList = menuList.stream().map(Menu::getPermission).collect(Collectors.toList());
			} else {
				Menu menu = new Menu();
	        	menu.setUserId(user.getId());
	        	List<Menu> menuList = menuDao.findByUserId(menu);
	        	permsList = menuList.stream().map(Menu::getPermission).collect(Collectors.toList());
			}
			permsSet = Sets.newHashSet();
			for (String perms : permsList) {
				if(StringUtils.isBlank(perms)){
	                continue;
	            }
	            permsSet.addAll(Arrays.asList(perms.trim().split(",")));
			}
			CacheUtils.put(CACHE_PERMISSION_LIST, CACHE_PERMISSION_LIST+"_"+user.getId(), permsSet);
		}
		return permsSet;
	}

}
